package cn.zhoujing.security.demo.service.impl;

import cn.zhoujing.security.demo.common.consts.AuthConst;
import cn.zhoujing.security.demo.common.enums.StatusEnum;
import cn.zhoujing.security.demo.common.exceptio.ValueTypeValidateException;
import cn.zhoujing.security.demo.entity.User;
import cn.zhoujing.security.demo.entity.UserDetail;
import cn.zhoujing.security.demo.service.UserRoleLinkService;
import cn.zhoujing.security.demo.service.UserService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 自定义用户查询
 *
 * @author zhoujing
 * @createTime 2024/02/07 - 19:22:00
 */
@Slf4j
@Component
public class DBUserDetailsServiceImpl implements UserDetailsService {



    @Lazy
    @Autowired
    private UserService userService;

    @Resource
    private UserRoleLinkService userRoleLinkService;

    /**
     * 根据用户id获取用户信息
     * <p>
     * 用户在登录时会调用此方法
     *
     * @param userIdStr 用户输入的id
     * @return 用户信息
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String userIdStr) throws UsernameNotFoundException {
        long userId = 0;
        try {
            userId = Long.parseLong(userIdStr);
        } catch (NumberFormatException e) {
            log.error("[登录]用户id：{}，用户id值非法", userIdStr);
            throw new ValueTypeValidateException("用户ID格式不合法，请输入有效数值");
        }
        User user = userService.getById(userId);
        if (Objects.isNull(user)) {
            log.error("[登录]用户id：{}，用户信息不存在", userIdStr);
            throw new UsernameNotFoundException("用户信息不存在");
        }
        if (user.getStatus().equals(StatusEnum.NOT_ENABLE.getCode())) {
            log.error("[登录]用户id：{}，用户信息被禁用", userIdStr);
            throw new DisabledException("用户已被禁用");
        }
        // 获取用户角色信息
        Set<String> roles = userRoleLinkService.getRoleCodesByUserId(userId);

        Set<SimpleGrantedAuthority> rolesSet = roles.stream().map(role -> new SimpleGrantedAuthority(AuthConst.ROLE_PREFIX + role)).collect(Collectors.toSet());
        return UserDetail.builder()
                .user(user)
                .authorities(rolesSet)
                .build();
    }

}
